/*
 * Class client.java
 * @author Guillermo Moraleda
 * @author Loles Salmeron
 *
 * Diffie-Hellman key exchange algorithm
 * over a TCP Socket.
 *
 */
package kau.cs.lab.connection;
import kau.cs.lab.blowfish.Blowfish;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.math.BigInteger;

class client {

    private final static int q = 23;
    private final static int g = 5;
    private static int A;
    private static int B;
    private static int a;
    private static BigInteger powresult;
    private static BigInteger big_a;
    private static BigInteger big_q;
    private static int key;

    public static void main(String argv[]) throws Exception {

        //Diffie-Hellman Algorithm

        a = (int) Math.round(Math.random() * 100);
        while (a >= q) {
            a = a - q;
        }
        A = (int) (Math.pow(g, a) % q);
        System.out.println("q = " + q + "\ng = " + g + "\na = " + a + "\nA = " + A);
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
        Socket clientSocket = new Socket("localhost", 6789);
        PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
        //DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        //Send A=g^a mod q
        outToServer.println(String.valueOf(A));
        //outToServer.writeBytes(String.valueOf(A) + '\n');


        //Receive B=g^b mod q
        B = Integer.parseInt(inFromServer.readLine());
        System.out.println("B = " + B);

        //Create Key
        powresult = new BigInteger(Integer.toString(B));
        big_a = new BigInteger(Integer.toString(a));
        big_q = new BigInteger(Integer.toString(q));
        key = (powresult.modPow(big_a, big_q)).intValue();

        //Read sentence from user
        System.out.println("Type the message to be encrypted:");
        byte[] message = "asdASDasd".getBytes();
        //String message = inFromUser.readLine();

        //Create BlowFish instance
        Blowfish bf = new Blowfish();
        bf.Blowfish_Init(intToByteArray(key));
        byte[] encrypted = bf.crypt(message, true);
        System.out.println("Plain Text      :" + new String(message));
        System.out.println("Plain Text Hex  :" + Blowfish.getHexString(message));
        System.out.println("Key             :" + key);
        System.out.println(encrypted);
        System.out.println("Cipher Text Hex :" + Blowfish.getHexString(encrypted));

        //Send to server
        outToServer.println(encrypted);

        //Receive from server
        encrypted = (inFromServer.readLine()).getBytes();

        //Decrypt and print
        byte[] decrypted = bf.crypt(encrypted, false);
        System.out.println("Plain Text      :" + new String(decrypted));

        //Close socket
        clientSocket.close();
    }

    public static final byte[] intToByteArray(int value) {
        return new byte[]{
                    (byte) (value >>> 24),
                    (byte) (value >>> 16),
                    (byte) (value >>> 8),
                    (byte) value};
    }
}
